#pragma once
#include "mysql.hpp"
#include "relation.hxx"
#include "relation-odb.hxx"

namespace mag {
    class RelationTable {
        public:
            using ptr = std::shared_ptr<RelationTable>;  // 用于简化指针类型声明
            // 构造函数，接受数据库连接对象
            RelationTable(const std::shared_ptr<odb::core::database> &db) : _db(db) {}

            // 新增关系信息
            bool insert(const std::string &uid, const std::string &pid) {
                try {
                    // 创建两个 Relation 对象，分别为 (uid, pid) 和 (pid, uid)，
                    // 表示双向的好友关系
                    Relation r1(uid, pid);
                    Relation r2(pid, uid);
                    
                    // 使用事务确保数据的一致性和原子性
                    odb::transaction trans(_db->begin());
                    
                    // 将两个关系对象持久化到数据库
                    _db->persist(r1);
                    _db->persist(r2);
                    
                    // 提交事务
                    trans.commit();
                } catch (std::exception &e) {
                    // 如果发生异常，记录错误日志并返回 false
                    LOG_ERROR("新增用户好友关系信息失败 {}-{}:{}！", uid, pid, e.what());
                    return false;
                }
                return true;  // 如果没有异常，返回 true
            }

            // 移除关系信息
            bool remove(const std::string &uid, const std::string &pid) {
                try {
                    // 使用事务确保删除操作的一致性
                    odb::transaction trans(_db->begin());
                    
                    // 查询并删除 (uid, pid) 和 (pid, uid) 这两个关系
                    typedef odb::query<Relation> query;
                    _db->erase_query<Relation>(query::user_id == uid && query::peer_id == pid);
                    _db->erase_query<Relation>(query::user_id == pid && query::peer_id == uid);
                    
                    // 提交事务
                    trans.commit();
                } catch (std::exception &e) {
                    // 如果发生异常，记录错误日志并返回 false
                    LOG_ERROR("删除好友关系信息失败 {}-{}:{}！", uid, pid, e.what());
                    return false;
                }
                return true;  // 如果没有异常，返回 true
            }

            // 判断关系是否存在
            bool exists(const std::string &uid, const std::string &pid) {
                typedef odb::query<Relation> query;
                typedef odb::result<Relation> result;
                result r;
                bool flag = false;
                try {
                    // 使用事务确保数据一致性
                    odb::transaction trans(_db->begin());
                    
                    // 查询是否存在 (uid, pid) 这个关系
                    r = _db->query<Relation>(query::user_id == uid && query::peer_id == pid);
                    
                    // 如果查询结果非空，说明关系存在
                    flag = !r.empty();
                    
                    // 提交事务
                    trans.commit();
                } catch (std::exception &e) {
                    // 如果发生异常，记录错误日志
                    LOG_ERROR("获取用户好友关系失败:{}-{}-{}！", uid, pid, e.what());
                }
                return flag;  // 返回查询结果
            }

            // 获取指定用户的好友ID
            std::vector<std::string> friends(const std::string &uid) {
                std::vector<std::string> res;
                try {
                    // 使用事务确保查询操作的一致性
                    odb::transaction trans(_db->begin());
                    
                    typedef odb::query<Relation> query;
                    typedef odb::result<Relation> result;
                    
                    // 查询该用户的所有好友关系 (user_id == uid)
                    result r(_db->query<Relation>(query::user_id == uid));
                    
                    // 遍历查询结果，将每个好友的 ID 添加到结果向量中
                    for (result::iterator i(r.begin()); i != r.end(); ++i) {
                        res.push_back(i->peer_id());
                    }
                    
                    // 提交事务
                    trans.commit();
                } catch (std::exception &e) {
                    // 如果发生异常，记录错误日志
                    LOG_ERROR("通过用户-{}的所有好友ID失败:{}！", uid, e.what());
                }
                return res;  // 返回好友列表
            }

        private:
            std::shared_ptr<odb::core::database> _db;  // 数据库连接对象
    };
}
